import { Mesh } from 'three/src/objects/Mesh'
import MeshUtil from '../../../renderExtension/utils/MeshUtil'
import { Point } from '../../../renderExtension/types/Point'
import Const from '../../../application/constants/Const'
import Polyline from '../../models/Polyline'
import { TransformControls } from 'three/examples/jsm/controls/TransformControls'
import Helper from '../../../utils/Helper'
import { App } from '../../../application'
import { Object3D, Raycaster, Sprite, Vector3 } from 'three'
import RouteArrow from './RouteArrow'
import RouteLine from './RouteLine'
import Poi2 from '../../models/Poi2'
import Events from '../../../application/constants/Events'
import EditFlight from '../EditFlight'

export default class Waypoint {
  private app: App
  private nodeArray: Array<Object3D> = new Array<Object3D>()
  private spriteTextArray: Array<Poi2> = new Array<Poi2>()
  private transformControls: TransformControls
  // private originNarrowMesh:Mesh;
  private nodeSphereRadius = 2.5
  private sphereAttachedPoint = 'sphereAttachedPoint'
  private verticalParam: { lineWidth: number; lineColor: string }
  private flightRange: { circelCenter: Point; circleRadius: number }
  private isStartDraging
  private pointIndex = -1
  // private isEditMode: boolean;
  private lastStatus: 'add' | 'select' //航点上次被操作的状态

  private defaultColor = '255,0,0'
  private selectColor = '255,255,0'

  private routeArrow: RouteArrow
  private routeLine: RouteLine
  private routePointParam: {
    grounds
    minDistanceFromGround: number
    maxDistanceFromGround: number
    sphereScale: number
    routeArrow: RouteArrow
    routeLine: RouteLine
    keybordDistance?: number
  }

  private globalClickCallback
  private scaleAllSpriteCallback
  private keydownCallback
  private keyupCallback
  private pressedKeys = new Set<string>()
  private moveAnimationId: number = null
  private selectedSphereMesh: Object3D = null

  public constructor(
    routePointParam: {
      grounds
      minDistanceFromGround: number
      maxDistanceFromGround: number
      sphereScale: number
      routeArrow: RouteArrow
      routeLine: RouteLine
      keybordDistance?: number
    },
    verticalParam: { lineWidth: number; lineColor: string },
    flightRange?: { circelCenter: Point; circleRadius: number }
  ) {
    this.app = App.getInstance()
    this.routePointParam = routePointParam
    this.verticalParam = verticalParam
    this.flightRange = flightRange

    this.routeArrow = this.routePointParam.routeArrow
    this.routeLine = this.routePointParam.routeLine

    this.initTransformControl()
    this.initRouteNode()

    this.scaleAllSpriteCallback = this.throttledScaleAllSprite.bind(this)
    this.app.on(Events.CameraChange, this.scaleAllSpriteCallback)

    this.keydownCallback = this.keydownListener.bind(this)
    this.app.on(Events.KeyDown, this.keydownCallback)

    this.keyupCallback = this.keyupListener.bind(this)
    this.app.on(Events.KeyUp, this.keyupCallback)
  }

  public startOperator(isEdit: boolean = true) {
    if (isEdit) {
      //编辑模式
      // this.isEditMode = true;

      if (this.selectedSphereMesh) {
        this.transformControls.attach(this.selectedSphereMesh)
      }
    } else {
      //选择模式
      // this.isEditMode = false;

      this.transformControls.detach()
    }

    this.nodeArray.forEach((sphere) => {
      // sphere['canNotSelect'] = false //开启射线拾取
    })
  }

  public dispose() {
    // this.isEditMode = false

    //清除各个节点上的球
    this.removeRouteNode()

    //清除控制器
    if (this.transformControls) {
      this.app.remove(this.transformControls.getHelper())
      this.transformControls.detach()
      this.transformControls.dispose()
      this.transformControls = null
    }

    // 清理键盘事件监听
    this.app.off(Events.KeyDown, this.keydownCallback)
    this.app.off(Events.KeyUp, this.keyupCallback)

    // 停止移动动画
    if (this.moveAnimationId) {
      cancelAnimationFrame(this.moveAnimationId)
      this.moveAnimationId = null
    }

    this.app.off(Events.Click, this.globalClickCallback)
    this.app.off(Events.CameraChange, this.scaleAllSpriteCallback)
  }

  private removeRouteNode() {
    //清除各个节点上的球
    this.nodeArray.forEach((element) => {
      MeshUtil.dispose(element)
    })
  }

  private originPosition: Vector3
  private initTransformControl() {
    this.transformControls = new TransformControls(
      this.app.three.camera,
      this.app.three.renderer.domElement
    )
    this.transformControls.enabled = true
    let self = this
    this.transformControls.addEventListener(
      'dragging-changed',
      function (event) {
        self.app.camera.orbit.enabled = !event.value
        self.isStartDraging = event.value
        let targetMesh = event.target.object
        if (self.isStartDraging == true) {
          self.pointIndex = -1

          self.routeArrow.removeLineNarrow()
          self.originPosition = targetMesh.position.clone()
        } else {
          self.updateRouteAfterControl(event)
          // self.pointIndex = -1
        }
      }
    )
    this.transformControls.addEventListener('change', function (event) {
      self.updateRouteWhileControl(event)
    })
    this.transformControls.setMode('translate')
    this.app.add(this.transformControls.getHelper())
  }

  private isInRange(point: Vector3) {
    let circelCenter = this.flightRange.circelCenter.clone().toEPSGWeb()
    point.z = 0

    let distance = point.distanceTo(circelCenter)
    if (distance > this.flightRange.circleRadius) {
      return false
    }
    return true
  }

  private handleCrossRange(
    tartetPosition,
    targetMesh,
    topPosition,
    isUpdateRouteLine
  ) {
    if (this.flightRange && !this.isInRange(tartetPosition.clone())) {
      //航点超出了最大范围
      this.app.fireEvent(Const.FlightRoute.crossRange)
      targetMesh.position.copy(this.originPosition)
      topPosition.copy(this.originPosition)

      if (isUpdateRouteLine) {
        let pointArray = this.routeLine.getPointArray()
        let newPoint = pointArray[this.pointIndex]
        newPoint.x = this.originPosition.x
        newPoint.y = this.originPosition.y
        newPoint.z = this.originPosition.z

        this.routeLine.updatePoint(this.pointIndex, newPoint, false)
      }
    }
  }

  private updateRouteAfterControl(event) {
    let targetMesh = event.target.object
    let targetPosition = targetMesh.position
    let topPosition = this.getVerticalTopPoint(targetPosition.clone())
    if (
      topPosition.z + this.routePointParam.minDistanceFromGround <=
        targetPosition.z &&
      targetPosition.z <= this.routePointParam.maxDistanceFromGround
    ) {
      this.handleCrossRange(targetPosition, targetMesh, topPosition, true)

      this.routeLine.intersectObjects() //检测线条是否和objArray中的mesh有相交，如果有相交，就从第一个相交点开始变化线条的颜色
      this.updateVerticalLine(targetMesh) //修改垂直线的高度
      this.routeArrow.initLineNarrow(true) //初始化箭头

      if (this.isStartDraging) {
        this.app.fireEvent(
          Const.FlightRoute.changeWayPoint,
          'updatePoint',
          this.pointIndex
        )
      }
      return
    }

    let dangerSign = 0 //危险标识，0标识高度太低，1标识高度太高
    if (
      topPosition.z + this.routePointParam.minDistanceFromGround >
      targetPosition.z
    ) {
      //航点的高度小于最低，需要调整高度
      topPosition.z += this.routePointParam.minDistanceFromGround
      dangerSign = 0
    } else if (targetPosition.z > this.routePointParam.maxDistanceFromGround) {
      //航点的高度大于最低，需要调整高度
      topPosition.z = this.routePointParam.maxDistanceFromGround
      dangerSign = 1
    }
    targetPosition.copy(topPosition)
    let lineNodePosition = targetMesh[this.sphereAttachedPoint]
    let pointArray = this.routeLine.getPointArray()
    for (let i = 0; i < pointArray.length; i++) {
      if (Helper.vector3Equals(pointArray[i], lineNodePosition)) {
        this.pointIndex = i
      }
    }

    this.handleCrossRange(targetPosition, targetMesh, topPosition, true)

    if (this.pointIndex != -1) {
      let newPoint = pointArray[this.pointIndex]
      newPoint.x = topPosition.x
      newPoint.y = topPosition.y
      newPoint.z = topPosition.z

      this.routeLine.updatePoint(this.pointIndex, newPoint, true)

      this.updateVerticalLine(targetMesh) //修改垂直线的高度
    }

    // this.routeLine.intersectObjects() //检测线条是否和objArray中的mesh有相交，如果有相交，就从第一个相交点开始变化线条的颜色
    targetMesh[this.sphereAttachedPoint] = topPosition.clone()

    this.routeArrow.initLineNarrow(true) //初始化箭头

    if (this.isStartDraging) {
      this.app.fireEvent(
        Const.FlightRoute.changeWayPoint,
        'updatePoint',
        this.pointIndex
      )
    }

    this.app.fireEvent(
      Const.FlightRoute.dangerWaypoint,
      dangerSign,
      this.pointIndex
    )
  }

  private updateRouteWhileControl(event) {
    if (!event.target.object) {
      return
    }

    let targetMesh = event.target.object
    let lineNodePosition = targetMesh[this.sphereAttachedPoint]
    let tartetPosition = targetMesh.position
    let pointArray = this.routeLine.getPointArray()
    if (this.isStartDraging == true) {
      for (let i = 0; i < pointArray.length; i++) {
        if (Helper.vector3Equals(pointArray[i], lineNodePosition)) {
          this.pointIndex = i
        }
      }

      if (this.pointIndex != -1) {
        let newPoint = pointArray[this.pointIndex]
        newPoint.x = tartetPosition.x
        newPoint.y = tartetPosition.y
        newPoint.z = tartetPosition.z

        this.routeLine.updatePoint(this.pointIndex, newPoint, false)
        this.updateVerticalLine(targetMesh)
      }
    }
    targetMesh[this.sphereAttachedPoint] = targetMesh.position.clone()
    if (this.isStartDraging) {
      this.app.fireEvent(
        Const.FlightRoute.changeWayPoint,
        'updatePoint',
        this.pointIndex
      )
    }
  }

  public getVerticalTopPoint(targetPosition) {
    let rayDirection = new Vector3(0, 0, -1)
    let rayBeginPosition = targetPosition
    rayBeginPosition.z = 100000
    let raycaster: Raycaster = new Raycaster(rayBeginPosition, rayDirection)
    raycaster.camera = this.app.three.camera
    try {
      let ground = this.routePointParam.grounds
      if (!ground || ground.length == 0) {
        ground = [this.app.three.scene]
      }
      let objArray = raycaster.intersectObjects(ground, true)
      if (objArray.length > 0) {
        let insertedPoint = objArray[0].point
        let newPoint = new Point(
          insertedPoint.x,
          insertedPoint.y,
          insertedPoint.z,
          Const.EPSGType.EPSGWeb
        )
        return newPoint
      }
    } catch (error) {
      console.log(error)
      return null
    }
    return null
  }

  private updateVerticalLine(targetMesh) {
    let children = targetMesh.children
    for (let i = 0; i < children.length; i++) {
      let curChild = children[i]
      if (curChild['verticalLine']) {
        let endPoint = new Point(
          0,
          0,
          -targetMesh.position.z,
          Const.EPSGType.EPSGWeb
        )
        let verticalLine = curChild as Polyline
        let verticalLineLastIndex = verticalLine.getPointArray().length - 1
        verticalLine.updatePoint(verticalLineLastIndex, endPoint)
      }
    }
  }

  private initRouteNode() {
    let pointArray = this.routeLine.getPointArray()
    let self = this
    pointArray.forEach((element) => {
      let sphereMesh = self.buildSphereMesh(element)
      self.nodeArray.push(sphereMesh)
    })

    this.setAllDefaultSprite()
  }

  public initRouteSign() {
    this.removeRouteNode()
    this.initRouteNode()

    this.routeArrow.removeLineNarrow()
    this.routeArrow.initLineNarrow()
  }

  private buildSphereMesh(sphereCenter: Point, canNotSelect = true) {
    // 使用 Object3D 作为容器，不再创建实际的球体几何
    let hideSphere = new Object3D()
    hideSphere['flightPointTag'] = true
    hideSphere[this.sphereAttachedPoint] = sphereCenter.clone()
    hideSphere.position.copy(sphereCenter.clone().toEPSGWeb())
    hideSphere['canNotSelect'] = false // 参与射线拾取
    hideSphere['flightClick'] = this.sphereClickEvent.bind(this)
    hideSphere['pickOrder'] = Const.PickIndex.flightPointIndex
    this.app.add(hideSphere)

    let indexText = (this.nodeArray.length + 1).toString()

    // 使用Poi2创建POI标记
    let poiMarker = new Poi2()

    // 使用batchUpdate方法设置POI属性 - 优化canvas尺寸 🎯
    poiMarker.batchUpdate({
      text: {
        name: indexText,
        color: 'white',
        // font: 'Arial',
        size: 48, // 减小字体大小从700px到48px，大幅减少canvas尺寸
        isBold: false
      },
      image: {
        size: 300 // 设置合理的图片尺寸，从默认1200px减少到64px
      },
      layout: {
        center: [0.5, 0.5], // 调整锚点为居中
        textPosition: 'center',
        showText: true // 确保文本显示
      },
      background: {
        color: this.defaultColor, // 背景色 - 使用红色
        opacity: 1,
        shape: 'circle', // 形状 (circle/rectangle)
        size: 1.2 // 稍微增大背景以适应较小的字体
      },
      shape: {
        color: 'transparent', // 将默认形状设为透明
        size: 0 // 将形状大小设为0
      },
      rendering: {
        depthTest: true // 启用深度测试
      }
    })

    // 添加自定义属性
    poiMarker['flightPointTag'] = true
    poiMarker['canNotSelect'] = false // 参与射线拾取
    poiMarker['flightClick'] = this.sphereClickEvent.bind(this)
    poiMarker['pickOrder'] = Const.PickIndex.flightPointIndex
    poiMarker['selectCount'] = 1 // 记录被选中的次数

    poiMarker.position.z += 0.3
    poiMarker.renderOrder = Const.RenderOrder.RouteLine + 1

    hideSphere.add(poiMarker)
    this.spriteTextArray.push(poiMarker)
    this.scaleSprite(poiMarker)

    this.buildVerticalLine(hideSphere)
    hideSphere['indexMarker'] = poiMarker

    return hideSphere
  }

  private scaleSprite(poiMarker: Poi2) {
    let cameraPosition = this.app.three.camera.position
    let worldPosition = poiMarker.getWorldPosition(new Vector3())
    let cameraViewDistance = cameraPosition.distanceTo(worldPosition)
    
    // 调整缩放逻辑：近距离固定为minScale，远距离时更大
    const minScale = 5
    const maxScale = 800.0  // 增大最大缩放值
    const baseDistance = 150  // 减小基础距离，让远距离时缩放更明显
    
    let scale = cameraViewDistance / baseDistance
    
    // 当距离很近时（scale < minScale），固定为minScale
    // 当距离远时，允许更大的缩放值
    scale = Math.max(minScale, Math.min(maxScale, scale))

    poiMarker.scale.set(scale, scale, scale)
  }

  // 移除节流限制，直接调用缩放方法，保持与旧版本一致
  private throttledScaleAllSprite() {
    this.scaleAllSprite()
  }

  private scaleAllSprite() {
    let self = this
    this.nodeArray.forEach((sphere, index) => {
      if (sphere['indexMarker']) {
        const poiMarker = sphere['indexMarker'] as Poi2
        // 只进行缩放计算，不更新文本内容以提升性能 🎯
        self.scaleSprite(poiMarker)
      }
    })
  }

  // 单独的文本更新方法，只在必要时调用
  private updateAllIndexText() {
    this.nodeArray.forEach((sphere, index) => {
      if (sphere['indexMarker']) {
        const poiMarker = sphere['indexMarker'] as Poi2
        // 使用batchUpdate方法更新POI的文本内容
        poiMarker.batchUpdate({
          text: {
            name: (index + 1).toString()
          },
          layout: {
            showText: true // 确保文本显示 🎯
          },
          background: {
            color: this.defaultColor, // 确保保持红色
            shape: 'circle',
            size: 0.9
          },
          rendering: {
            depthTest: true // 启用深度测试
          }
        })

        // 重新应用固定缩放，防止batchUpdate重置缩放 🎯
        this.scaleSprite(poiMarker)
      }
    })
  }

  private keydownListener(e: KeyboardEvent) {
    if (!this.transformControls.object || this.pointIndex === -1) {
      return
    }

    // 将当前按下的键添加到Set集合中
    if (!this.pressedKeys.has(e.key)) {
      this.pressedKeys.add(e.key)
      // 开始持续移动动画
      this.startContinuousMove()
    }
  }

  private startContinuousMove() {
    if (this.moveAnimationId) {
      return // 已经在运行了
    }

    const moveStep = () => {
      if (this.pressedKeys.size === 0) {
        // 没有按键了，停止动画
        this.moveAnimationId = null
        return
      }

      let moveDistance = this.routePointParam.keybordDistance || 1
      let pointArray = this.routeLine.getPointArray()
      let newPosition = pointArray[this.pointIndex].clone()

      // 计算所有方向的移动向量（dx=左右, dy=前后, dz=上下）
      let dx = 0,
        dy = 0,
        dz = 0
      if (this.pressedKeys.has('a') || this.pressedKeys.has('ArrowLeft')) {
        dx -= moveDistance
      }
      if (this.pressedKeys.has('d') || this.pressedKeys.has('ArrowRight')) {
        dx += moveDistance
      }
      if (this.pressedKeys.has('w') || this.pressedKeys.has('ArrowUp')) {
        dy += moveDistance
      }
      if (this.pressedKeys.has('s') || this.pressedKeys.has('ArrowDown')) {
        dy -= moveDistance
      }
      if (this.pressedKeys.has('c')) {
        dz += moveDistance
      }
      if (this.pressedKeys.has('z')) {
        dz -= moveDistance
      }

      // 应用移动向量
      newPosition.x += dx
      newPosition.y += dy
      newPosition.z += dz

      EditFlight.instance.updatePoint(this.pointIndex, newPosition, true)

      // 继续下一帧
      this.moveAnimationId = requestAnimationFrame(moveStep)
    }

    this.moveAnimationId = requestAnimationFrame(moveStep)
  }

  private keyupListener(e: KeyboardEvent) {
    // 从Set集合中移除释放的键
    this.pressedKeys.delete(e.key)

    // 如果没有按键了，停止动画
    if (this.pressedKeys.size === 0 && this.moveAnimationId) {
      cancelAnimationFrame(this.moveAnimationId)
      this.moveAnimationId = null
    }
  }

  private setAllDefaultSprite(selectPoi: Poi2 = null) {
    let sphereIndex = -1
    // 先重置所有航点的样式为默认样式
    this.nodeArray.forEach((sphere, index) => {
      let poiMarker = sphere['indexMarker'] as Poi2

      // 使用batchUpdate方法更新POI样式 - 改为修改background而不是shape
      poiMarker.batchUpdate({
        background: {
          color: this.defaultColor, // 使用红色作为默认颜色
          shape: 'circle',
          size: 0.9
        },
        shape: {
          color: 'transparent',
          size: 0
        },
        rendering: {
          depthTest: true // 启用深度测试
        }
      })

      // 重新应用固定缩放，防止batchUpdate重置缩放 🎯
      this.scaleSprite(poiMarker)

      if (poiMarker == selectPoi) {
        sphereIndex = index
      }
    })
    return sphereIndex
  }

  private buildVerticalLine(parentMesh: Object3D) {
    let endPoint = new Point(
      0,
      0,
      -parentMesh.position.z,
      Const.EPSGType.EPSGWeb
    )
    let pointArray = [
      //3857表示web墨卡托坐标系，4326表示经纬度坐标
      new Point(0, 0, 0, Const.EPSGType.EPSGWeb),
      endPoint
    ]
    let lineData = {
      pointArray: pointArray, //多边形的顶点数组
      color: this.verticalParam.lineColor,
      lineWidth: this.verticalParam.lineWidth, //线的宽度
      depthTest: true
    }
    let polyline = new Polyline(lineData)
    polyline['verticalLine'] = polyline
    parentMesh.add(polyline)
  }

  private sphereClickEvent(e) {
    // if (!this.isEditMode && !this.isSelectMode) {
    //   this.selectedSphereMesh = null;
    //   return false;
    // }
    let lastSelectPoi
    if (this.selectedSphereMesh) {
      lastSelectPoi = this.selectedSphereMesh['indexMarker']
    }

    let curObject = e.object
    let poiMarker
    if (curObject instanceof Poi2) {
      poiMarker = curObject
      curObject = curObject.parent
    } else {
      poiMarker = curObject['indexMarker']
    }

    if (lastSelectPoi != poiMarker) {
      this.clearSelectCount()
      this.transformControls.detach()
    }
    poiMarker['selectCount'] += 1

    this.pointIndex = this.setAllDefaultSprite(poiMarker)

    // 使用batchUpdate方法更新选中POI的样式 - 改为修改background颜色
    poiMarker.batchUpdate({
      background: {
        color: this.selectColor,
        shape: 'circle',
        size: 0.9
      },
      shape: {
        color: 'transparent',
        size: 0
      },
      rendering: {
        depthTest: true // 启用深度测试
      }
    })

    // 重新应用固定缩放，防止batchUpdate重置缩放 🎯
    this.scaleSprite(poiMarker)

    if (this.pointIndex != -1) {
      this.app.fireEvent(
        Const.FlightRoute.changeWayPoint,
        'selectPoint',
        this.pointIndex
      )
    }

    if (poiMarker['selectCount'] > 1) {
      this.transformControls.attach(curObject)
      this.app.fireEvent('editWaypoint', true)
    }
    this.lastStatus = 'select'
    this.selectedSphereMesh = curObject
    return true
  }

  private clearSelectCount() {
    this.nodeArray.forEach((sphere, index) => {
      let poiMarker = sphere['indexMarker'] as Poi2
      poiMarker['selectCount'] = 0
    })
  }

  public unSelectClickEvent(e?) {
    // if (!this.isEditMode && !this.isSelectMode) {
    //   this.selectedSphereMesh = null;
    //   return
    // }

    if (!e || !e.object['flightRouteTag'] || !e.object['flightPointTag']) {
      //选中的不是航线或者航点
      this.clearSelectCount()
      this.setAllDefaultSprite(null)

      this.transformControls.detach()

      if (this.selectedSphereMesh) {
        this.selectedSphereMesh = null
        this.app.fireEvent(Const.FlightRoute.changeWayPoint, 'unSelectPoint')
      }
    }
  }

  public pointClickEvent(insertedPointMsg) {
    this.transformControls.detach()
    // 先重置所有航点的样式为默认样式
    this.setAllDefaultSprite()

    let sphereMesh = this.buildSphereMesh(insertedPointMsg.insertedPoint, false)
    this.nodeArray.splice(insertedPointMsg.fitIndex + 1, 0, sphereMesh)

    // 更新所有点的序号
    this.updateAllIndexMarkers()

    let poiMarker = sphereMesh['indexMarker'] as Poi2
    // 使用batchUpdate方法更新选中POI的样式 - 改为修改background颜色
    poiMarker.batchUpdate({
      background: {
        color: this.selectColor,
        shape: 'circle',
        size: 0.9
      },
      shape: {
        color: 'transparent',
        size: 0
      },
      rendering: {
        depthTest: true // 启用深度测试
      }
    })

    // 重新应用固定缩放，防止batchUpdate重置缩放 🎯
    this.scaleSprite(poiMarker)

    this.selectedSphereMesh = sphereMesh
    // this.transformControls.attach(this.selectedSphereMesh)
  }

  // 添加更新所有序号的方法
  private updateAllIndexMarkers() {
    // 使用优化后的文本更新方法 🎯
    this.updateAllIndexText()
    // 执行一次缩放更新
    this.scaleAllSprite()
  }

  public selectWayPoint(index) {
    this.setAllDefaultSprite()

    let selectSphereMesh = this.nodeArray[index]
    this.selectedSphereMesh = selectSphereMesh
    let poiMarker = selectSphereMesh['indexMarker'] as Poi2

    // 使用batchUpdate方法更新选中POI的样式 - 改为修改background颜色
    poiMarker.batchUpdate({
      background: {
        color: this.selectColor,
        shape: 'circle',
        size: 0.9
      },
      shape: {
        color: 'transparent',
        size: 0
      },
      rendering: {
        depthTest: true // 启用深度测试
      }
    })

    // 重新应用固定缩放，防止batchUpdate重置缩放 🎯
    this.scaleSprite(poiMarker)

    // if(this.isEditMode){
    this.transformControls.attach(selectSphereMesh)
    // }
    this.lastStatus = 'select'
  }

  public addWaypoint(point) {
    this.transformControls.detach()
    this.setAllDefaultSprite()

    if (this.selectedSphereMesh && this.lastStatus == 'select') {
      this.selectedSphereMesh = null
      this.app.fireEvent(Const.FlightRoute.changeWayPoint, 'unSelectPoint')
    }

    let sphereMesh = this.buildSphereMesh(point)
    this.nodeArray.push(sphereMesh)
    let poiMarker = sphereMesh['indexMarker'] as Poi2
    this.spriteTextArray.push(poiMarker)

    // 更新所有航点的序号文本和缩放 🎯
    this.updateAllIndexMarkers()

    this.selectedSphereMesh = sphereMesh
    this.lastStatus = 'add'
    
    // 设置新添加的航点为黄色选中状态 🎯
    poiMarker.batchUpdate({
      background: {
        color: this.selectColor, // 使用黄色作为选中颜色
        shape: 'circle',
        size: 0.9
      },
      rendering: {
        depthTest: true
      }
    })
    
    // 重新应用缩放，防止batchUpdate重置缩放
    this.scaleSprite(poiMarker)
  }

  public removeWaypoint(index: number) {
    let sphereMesh = this.nodeArray[index]
    if (this.transformControls.object == sphereMesh) {
      this.transformControls.detach()
    }
    MeshUtil.dispose(sphereMesh)
    this.nodeArray.splice(index, 1)

    // 更新剩余点的序号
    this.updateAllIndexText() // 只更新文本，提升性能 🎯
  }

  public updateWaypoint(index: number, newPoint: Point) {
    let sphereMesh = this.nodeArray[index]
    sphereMesh.position.copy(newPoint.clone().toEPSGWeb())

    this.updateVerticalLine(sphereMesh) //修改垂直线的高度
  }
}
